import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_aliyun_nui/flutter_aliyun_nui.dart';

void main() {
  group('NuiErrorType Tests', () {
    test('should create error from code correctly', () {
      // Test known error codes
      expect(NuiErrorType.fromCode(40000000), NuiErrorType.clientError);
      expect(NuiErrorType.fromCode(40000001), NuiErrorType.tokenExpiredOrInvalid);
      expect(NuiErrorType.fromCode(40000002), NuiErrorType.messageInvalid);
      expect(NuiErrorType.fromCode(40000003), NuiErrorType.parameterInvalid);
      expect(NuiErrorType.fromCode(40000005), NuiErrorType.tooManyRequests);
      expect(NuiErrorType.fromCode(40000009), NuiErrorType.invalidWavHeader);
      
      // Test unknown error code
      expect(NuiErrorType.fromCode(99999), NuiErrorType.unknown);
      expect(NuiErrorType.fromCode(-1), NuiErrorType.unknown);
    });

    test('should have correct error properties', () {
      const tokenError = NuiErrorType.tokenExpiredOrInvalid;
      expect(tokenError.code, 40000001);
      expect(tokenError.message, 'Token已过期或无效');
      expect(tokenError.description, '通用客户端错误，通常是涉及Token相关的不正确使用，例如Token过期或者非法');
    });
  });

  group('NuiError Tests', () {
    test('should create error from map correctly', () {
      final map = {
        'errorCode': 40000001,
        'errorMessage': 'Token expired',
      };
      
      final error = NuiError.fromMap(map);
      expect(error.errorCode, 40000001);
      expect(error.errorMessage, 'Token expired');
      expect(error.errorType, NuiErrorType.tokenExpiredOrInvalid);
    });

    test('should create error from type correctly', () {
      final error = NuiError.fromType(NuiErrorType.parameterInvalid);
      expect(error.errorCode, 40000003);
      expect(error.errorMessage, '用户传递的参数有误');
      expect(error.errorType, NuiErrorType.parameterInvalid);
    });

    test('should create error from type with custom message', () {
      final error = NuiError.fromType(
        NuiErrorType.parameterInvalid,
        customMessage: 'Custom parameter error message',
      );
      expect(error.errorCode, 40000003);
      expect(error.errorMessage, 'Custom parameter error message');
      expect(error.errorType, NuiErrorType.parameterInvalid);
    });

    test('should identify error types correctly', () {
      final tokenError = NuiError.fromType(NuiErrorType.tokenExpiredOrInvalid);
      expect(tokenError.isTokenError, true);
      expect(tokenError.isParameterError, false);
      expect(tokenError.isNetworkError, false);
      expect(tokenError.isAudioFormatError, false);

      final paramError = NuiError.fromType(NuiErrorType.parameterInvalid);
      expect(paramError.isTokenError, false);
      expect(paramError.isParameterError, true);
      expect(paramError.isNetworkError, false);
      expect(paramError.isAudioFormatError, false);

      final networkError = NuiError.fromType(NuiErrorType.tooManyRequests);
      expect(networkError.isTokenError, false);
      expect(networkError.isParameterError, false);
      expect(networkError.isNetworkError, true);
      expect(networkError.isAudioFormatError, false);

      final audioError = NuiError.fromType(NuiErrorType.invalidWavHeader);
      expect(audioError.isTokenError, false);
      expect(audioError.isParameterError, false);
      expect(audioError.isNetworkError, false);
      expect(audioError.isAudioFormatError, true);
    });

    test('should provide user-friendly messages', () {
      final tokenError = NuiError.fromType(NuiErrorType.tokenExpiredOrInvalid);
      expect(tokenError.userFriendlyMessage, 'Token已过期，请重新获取');

      final paramError = NuiError.fromType(NuiErrorType.parameterInvalid);
      expect(paramError.userFriendlyMessage, '参数配置错误，请检查配置');

      final networkError = NuiError.fromType(NuiErrorType.tooManyRequests);
      expect(networkError.userFriendlyMessage, '请求过于频繁，请稍后重试');

      final audioError = NuiError.fromType(NuiErrorType.invalidWavHeader);
      expect(audioError.userFriendlyMessage, '音频格式不正确，请检查音频设置');
    });

    test('should handle equality correctly', () {
      final error1 = NuiError.fromType(NuiErrorType.tokenExpiredOrInvalid);
      final error2 = NuiError.fromType(NuiErrorType.tokenExpiredOrInvalid);
      final error3 = NuiError.fromType(NuiErrorType.parameterInvalid);

      expect(error1, error2);
      expect(error1, isNot(error3));
    });

    test('should provide correct toString representation', () {
      final error = NuiError.fromType(NuiErrorType.tokenExpiredOrInvalid);
      final expectedString = 'NuiError(code: 40000001, message: Token已过期或无效, type: tokenExpiredOrInvalid)';
      expect(error.toString(), expectedString);
    });

    test('should handle unknown error codes in fromMap', () {
      final map = {
        'errorCode': 99999,
        'errorMessage': 'Unknown error',
      };
      
      final error = NuiError.fromMap(map);
      expect(error.errorCode, 99999);
      expect(error.errorMessage, 'Unknown error');
      expect(error.errorType, NuiErrorType.unknown);
    });

    test('should handle missing fields in fromMap', () {
      final map = <String, dynamic>{};
      
      final error = NuiError.fromMap(map);
      expect(error.errorCode, -1);
      expect(error.errorMessage, 'Unknown error');
      expect(error.errorType, NuiErrorType.unknown);
    });
  });
}